package pt.isec.a21210392.a21190220.ludotwist;

import java.io.ObjectInputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

import pt.isec.a21210392.a21190220.ludotwist.GameLogic.Game;
import pt.isec.a21210392.a21190220.ludotwist.GameLogic.Human;
import pt.isec.a21210392.a21190220.ludotwist.GameLogic.Player;
import android.app.Activity;
import android.content.Intent;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.StrictMode;
import android.text.format.Formatter;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;

public class HostGameActivity extends Activity 
{
	protected boolean start = false;
	protected TextView gameSetup;
	private HostThread hostThread;
	public static Socket socket;
	public static ObjectInputStream in;
	private String ipAddress;
	private ServerSocket hostGameSocket;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_host_game);
		
		StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
		StrictMode.setThreadPolicy(policy); 
		WifiManager wifiMgr = (WifiManager) getSystemService(WIFI_SERVICE);
		WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
		int ip = wifiInfo.getIpAddress();
		ipAddress = Formatter.formatIpAddress(ip);
		
		gameSetup = (TextView)findViewById(R.id.game_setup);
		hostThread = new HostThread(HostGameActivity.this);
		hostThread.start();
	}
	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.host_game, menu);
		return true;
	}
	@Override
	protected void onDestroy() 
	{
		try
		{
			hostGameSocket.close();
		}
		catch(Exception e){Log.d("Exception",e.getMessage().toString());}
		super.onDestroy();
	}
	
	public void onStartClick(View v)
	{
		start = true;
		hostThread.joinGame();
		
		try
		{
			hostGameSocket.close();		
			in = new ObjectInputStream(socket.getInputStream());
			
			Message message = (Message)in.readObject();
			
			if(message.getMessage().equals(Constants.START))
			{				
				Intent myIntent = new Intent(HostGameActivity.this,GameActivity.class);
				myIntent.putExtra("fromHost", true);
				myIntent.putExtra("players", hostThread.players.size());
				myIntent.putExtra("number", (Integer)message.getObject());
				HostGameActivity.this.startActivity(myIntent);
			}
		}
		catch(Exception e){Log.d("Em host activity: ", e.getMessage().toString());}
	}
	
	public class HostThread extends Thread
	{
		private HostGameActivity hostActivity;
		private Socket player;
		private PlayerThreadOnHost playerThread;
		private ArrayList<PlayerThreadOnHost> players;
		
		public HostThread(HostGameActivity hostActivity)
		{
			this.hostActivity = hostActivity;
			players = new ArrayList<PlayerThreadOnHost>();
		}
		
		public void joinGame()
		{
			int i = 0;
			for (PlayerThreadOnHost thread: players)
			{
				thread.joinGame(i);
				i++;
			}
		}
		public void sendName(Human human)
		{
			for (PlayerThreadOnHost thread: players)
			{
				thread.sendName(human);
			}
		}
		public void play(Game game)
		{
			for (PlayerThreadOnHost thread: players)
			{
				thread.play(game);
			}
		}
		public void updateBoard(ArrayList<ToDraw> draws, PlayerThreadOnHost sender)
		{
			for (PlayerThreadOnHost thread: players)
			{
				if (!thread.equals(sender))
				{
					thread.updateBoard(draws);
				}
			}
		}
		public void updateDice(int result, PlayerThreadOnHost sender)
		{
			for (PlayerThreadOnHost thread: players)
			{
				if (!thread.equals(sender))
				{
					thread.updateDice(result);
				}
			}
		}
		public void finishTurn(Game game)
		{
			for (PlayerThreadOnHost thread: players)
			{
				thread.finishTurn(game);
			}
		}
		public void finishPlay(Player winner)
		{
			for (int i=0; i<players.size();i++)
			{
				try
				{
					players.get(i).finishPlay(winner);
				}
				catch(Exception e)
				{
					players.remove(i);
					i--;
				}
			}
		}
		public void runOnUI(String text)
		{
			final String finalText = text;
			runOnUiThread(new Runnable() 
			{
				@Override
				public void run() 
				{
					hostActivity.gameSetup.setText(hostActivity.gameSetup.getText()+finalText);							
				}
			});
		}
		
		@Override
		public void run()
		{
			try
			{
				hostGameSocket = new ServerSocket(Constants.PORT);
				runOnUI("HOST_IP : " + ipAddress + "\n\n" + R.string.hg_players);
				socket = new Socket(InetAddress.getLocalHost(), Constants.PORT);
				
				while(!start)
				{
					player = hostGameSocket.accept();
					if (!start && players.size() != 4)
					{
						playerThread = new PlayerThreadOnHost(this,player);
						players.add(playerThread);
						playerThread.start();
						runOnUI("\n" + player.getInetAddress().getHostAddress());
					}
				}
			}
			catch(Exception e){Log.d("Exception: ", e.getMessage().toString());}
			finally
			{
				for (PlayerThreadOnHost thread: players)
				{
					try
					{
						thread.join();
					}
					catch(Exception e){};
				}
				HostGameActivity.this.finish();
			}
		}
	}
}
